/**
 * Key
 * 
 * @author		Allen Chou
 * @version		1.0.1 (last update: Dec 20 2007)
 * @link		http://cjcat2266.deviantart.com
 */

/**
 * The code is modified from the original "KeyObject" class by Senocular(Trevor McCauley)
 * you can visit his site at http://www.senocular.com
 */

package idv.cjcat.ui {
    import flash.display.*;
    import flash.events.*;
	import flash.errors.*;
    
	/**
	 * This class simulates the <code>Key</code> class in ActionScript 2.0.
	 * The only difference is that before using this class, <code>Key.init(stage)</code> should be called first (and once).
	 * The <code>stage</code> parameter is the reference to the <code>Stage</code> instance.
	 */
	
    public final class Key {
        
        private static var initialized:Boolean = false;
        private static var keysDown:Object = new Object();
        
        /**
         * Initializes the <code>Key</code> class creating assigning event.
         * Before using <code>Key.isDown(keyCode)</code>, this method should be called first (and once).
		 * 
		 * @param stage  The reference to the <code>Stage</code> instance.
		 * 
		 * <listing>
		 * import idv.cjcat.ui.Key;
		 * Key.init(stage);</listing>
		 * 
         */
        public static function init(stage:Stage):void {
            if (!initialized) {
                // assign listeners for key presses and deactivation of the player
                stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed, false, int.MAX_VALUE);
                stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased, false, int.MAX_VALUE);
                stage.addEventListener(Event.DEACTIVATE, clearKeys);
                
                // mark initialization as true so redundant
                // calls do not reassign the event handlers
                initialized = true;
            }
        }
        
        /**
         * Check if the key specified by <code>keyCode</code> is pressed down.
		 * @param  Key code of the key to be checked.
		 * @return Whether the key specified by <code>keyCode</code> is pressed down.
         */
        public static function isDown(keyCode:uint):Boolean {
            if (!initialized) {
                // throw an error if isDown is used
                // prior to Key class initialization
                throw new IllegalOperationError("Key class has not yet been initialized.");
            }
            return Boolean(keyCode in keysDown);
        }
        
        /**
         * Event handler for capturing keys being pressed
         */
        private static function keyPressed(event:KeyboardEvent):void {
            // create a property in keysDown with the name of the keyCode
            keysDown[event.keyCode] = true;
        }
        
        /**
         * Event handler for capturing keys being released
         */
        private static function keyReleased(event:KeyboardEvent):void {
            if (event.keyCode in keysDown) {
                // delete the property in keysDown if it exists
                delete keysDown[event.keyCode];
            }
        }
        
        /**
         * Event handler for Flash Player deactivation
         */
        private static function clearKeys(event:Event):void {
            // clear all keys in keysDown since the player cannot
            // detect keys being pressed or released when not focused
            keysDown = new Object();
        }
		
    }
} 